package com.fly.docker.web;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fly.core.entity.JsonResult;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.spotify.docker.client.DefaultDockerClient;
import com.spotify.docker.client.DockerClient;
import com.spotify.docker.client.DockerClient.ListContainersParam;
import com.spotify.docker.client.exceptions.DockerException;
import com.spotify.docker.client.messages.ContainerConfig;
import com.spotify.docker.client.messages.ContainerCreation;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/test")
@Api(tags = "测试")
public class TestController
{
    DockerClient dockerClient = new DefaultDockerClient("unix:///var/run/docker.sock");
    
    @ApiOperation("启动容器")
    @ApiOperationSupport(order = 10)
    @GetMapping("/start")
    public JsonResult<?> startContainers()
        throws DockerException, InterruptedException
    {
        // 拉取image
        String imageName = "tomcat:alpine";
        dockerClient.pull(imageName);
        // 创建并启动
        ContainerConfig containerConfig = ContainerConfig.builder().image(imageName).build();
        for (int i = 0; i < 5; i++)
        {
            String containerName = "tomcat-" + DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd-HHmmssSSS");
            ContainerCreation container = dockerClient.createContainer(containerConfig, containerName);
            dockerClient.startContainer(container.id());
            TimeUnit.MICROSECONDS.sleep(RandomUtils.nextLong(100, 1000));
        }
        return JsonResult.success();
    }
    
    @ApiOperation("kill容器")
    @ApiOperationSupport(order = 20)
    @PostMapping("/kill")
    public JsonResult<?> killContainers(String name)
        throws DockerException, InterruptedException
    {
        try
        {
            dockerClient.listContainers(ListContainersParam.allContainers()).stream().filter(c -> StringUtils.contains(Objects.toString(c.names()), name)).forEach(c -> {
                try
                {
                    log.info("#### will kill container named {}", c.names());
                    dockerClient.killContainer(c.id());
                }
                catch (DockerException | InterruptedException e)
                {
                    log.error(e.getMessage(), e);
                }
            });
            log.info("--------------------------");
        }
        catch (DockerException | InterruptedException e)
        {
            log.error(e.getMessage(), e);
        }
        return JsonResult.success();
    }
    
    @ApiOperation("remove容器")
    @ApiOperationSupport(order = 30)
    @PostMapping("/remove")
    public JsonResult<?> removeContainers(String name)
        throws DockerException, InterruptedException
    {
        try
        {
            dockerClient.listContainers(ListContainersParam.allContainers()).stream().filter(c -> StringUtils.contains(Objects.toString(c.names()), name)).forEach(c -> {
                try
                {
                    log.info("#### will kill container named {}", c.names());
                    dockerClient.removeContainer(c.id());
                }
                catch (DockerException | InterruptedException e)
                {
                    log.error(e.getMessage(), e);
                }
            });
            log.info("--------------------------");
        }
        catch (DockerException | InterruptedException e)
        {
            log.error(e.getMessage(), e);
        }
        return JsonResult.success();
    }
}
